
#ifndef SYLAR_LOG_H
#define SYLAR_LOG_H

#include <string>
#include <vector>
#include <memory>
#include <ostream>
#include <sstream>
#include <time.h>
#include <iostream>
#include <map>
#include <chrono>
#include <list>
#include <fstream>
#include "util.h"
#include "singleton.h"
#include <cstdarg>
#include "yaml-cpp/yaml.h"
#include "comment.h"
#include "thread.h"
// 基础日志级别宏（带流式操作）
#define SYLAR_LOG_LEVEL(logger, level)                                                                                                      \
    if ((logger)->getLevel() <= (level))                                                                                                    \
    sylar::LogEventWrap(logger,                                                                                                             \
                        std::make_shared<sylar::LogEvent>(logger, level, __FILE__, __LINE__,                                                \
                                                          sylar::GetElapse(), sylar::GetThreadId(), sylar::GetFiberId(), sylar::GetTime(),sylar::Thread::GetName()), \
                        level)                                                                                                              \
        .getSS()

// 初始化宏（确保单例日志器被初始化）
#define SYLAR_LOG_INIT()                     \
    do                                       \
    {                                        \
        sylar::InitUtil();                   \
        /* 触发日志器管理单例初始化 */       \
        sylar::LoggerManager::GetInstance(); \
    } while (0)
// 各级别流式日志宏
#define SYLAR_LOG_DEBUG(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::DEBUG)
#define SYLAR_LOG_INFO(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::INFO)
#define SYLAR_LOG_WARN(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::WARN)
#define SYLAR_LOG_ERROR(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::ERROR)
#define SYLAR_LOG_FATAL(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::FATAL)

// 格式化日志宏
#define SYLAR_LOG_FMT_LEVEL(logger, level, fmt, ...)                                                                                         \
    do                                                                                                                                       \
    {                                                                                                                                        \
        if ((logger)->getLevel() <= (level))                                                                                                 \
        {                                                                                                                                    \
            auto event = std::make_shared<sylar::LogEvent>(logger, level, __FILE__, __LINE__,                                                \
                                                           sylar::GetElapse(), sylar::GetThreadId(), sylar::GetFiberId(), sylar::GetTime(),sylar::Thread::GetName()); \
            event->format(fmt, ##__VA_ARGS__);                                                                                               \
            (logger)->log(level, event);                                                                                                     \
        }                                                                                                                                    \
    } while (0)

// 各级别格式化日志宏
#define SYLAR_LOG_FMT_DEBUG(logger, fmt, ...) SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::DEBUG, fmt, ##__VA_ARGS__)
#define SYLAR_LOG_FMT_INFO(logger, fmt, ...) SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::INFO, fmt, ##__VA_ARGS__)
#define SYLAR_LOG_FMT_WARN(logger, fmt, ...) SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::WARN, fmt, ##__VA_ARGS__)
#define SYLAR_LOG_FMT_ERROR(logger, fmt, ...) SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::ERROR, fmt, ##__VA_ARGS__)
#define SYLAR_LOG_FMT_FATAL(logger, fmt, ...) SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::FATAL, fmt, ##__VA_ARGS__)

// 修正后的日志宏（去掉XX和#XX，直接传递格式字符串和参数）
#define SYLAR_LOG_D(...) SYLAR_LOG_FMT_DEBUG(sylar::LoggerManager::GetInstance()->getDebugLogger(), __VA_ARGS__)
#define SYLAR_LOG_I(...) SYLAR_LOG_FMT_INFO(sylar::LoggerManager::GetInstance()->getInfoLogger(), __VA_ARGS__)
#define SYLAR_LOG_W(...) SYLAR_LOG_FMT_WARN(sylar::LoggerManager::GetInstance()->getWarnLogger(), __VA_ARGS__)
#define SYLAR_LOG_E(...) SYLAR_LOG_FMT_ERROR(sylar::LoggerManager::GetInstance()->getErrorLogger(), __VA_ARGS__)
#define SYLAR_LOG_F(...) SYLAR_LOG_FMT_FATAL(sylar::LoggerManager::GetInstance()->getFatalLogger(), __VA_ARGS__)

#define SYLAR_LOG_D_STREAM() SYLAR_LOG_DEBUG(sylar::LoggerManager::GetInstance()->getDebugLogger())
#define SYLAR_LOG_I_STREAM() SYLAR_LOG_INFO(sylar::LoggerManager::GetInstance()->getInfoLogger())
#define SYLAR_LOG_W_STREAM() SYLAR_LOG_WARN(sylar::LoggerManager::GetInstance()->getWarnLogger())
#define SYLAR_LOG_E_STREAM() SYLAR_LOG_ERROR(sylar::LoggerManager::GetInstance()->getErrorLogger())
#define SYLAR_LOG_F_STREAM() SYLAR_LOG_FATAL(sylar::LoggerManager::GetInstance()->getFatalLogger())

#define SYLAR_LOG_STREAM() SYLAR_LOG_INFO(sylar::LoggerManager::GetInstance()->getDebugLogger())
#define SYLAR_LOG(...) SYLAR_LOG_FMT_INFO(sylar::LoggerManager::GetInstance()->getDebugLogger(), __VA_ARGS__)
// 获取各默认级别日志器的单例指针
#define SYLAR_DEBUG_LOGGER() sylar::LoggerManager::GetInstance()->getDebugLogger()
#define SYLAR_INFO_LOGGER() sylar::LoggerManager::GetInstance()->getInfoLogger()
#define SYLAR_WARN_LOGGER() sylar::LoggerManager::GetInstance()->getWarnLogger()
#define SYLAR_ERROR_LOGGER() sylar::LoggerManager::GetInstance()->getErrorLogger()
#define SYLAR_FATAL_LOGGER() sylar::LoggerManager::GetInstance()->getFatalLogger()

#define SYLAR_LOGGER() SYLAR_INFO_LOGGER()

#define SYLAR_LOG_NAME(name) sylar::LoggerManager::GetInstance()->getLogger(name)

#define SYLAR_LOG_ROOT()  sylar::LoggerManager::GetInstance()->getLogger("root")


#define SS() SYLAR_LOG_INFO(SYLAR_INFO_LOGGER())

namespace sylar
{
    class LogLevel
    {
    public:
        enum Level
        {
            /// 致命情况，系统不可用
            FATAL = 10000,
            /// 高优先级情况，例如数据库系统崩溃
            ALERT = 9000,
            /// 严重错误，例如硬盘错误
            CRIT = 8000,
            /// 错误
            ERROR = 7000,
            // 未知

            /// 警告
            WARN = 6000,
            /// 正常但值得注意
            NOTICE = 5000,
            /// 一般信息
            INFO = 4000,
            /// 调试信息
            DEBUG = 3000,
            /// 未设置
            NOTSET = 2000,
            UNKNOWN = 1000
        };
        static const char *ToString(Level level);
        static Level FromString(const std::string &str);
    };

    // 日志事件
    class Logger;

    class LogEvent
    {
    public:
        using ptr = std::shared_ptr<LogEvent>;
        LogEvent(std::shared_ptr<class Logger> logger, LogLevel::Level level, const char *file, int32_t line, uint32_t elapse, uint32_t thread_id, uint32_t fiber_id, uint64_t time,const std::string& thread_name) : m_time(time) // 1. 对应第1个声明的m_time
                                                                                                                                                                                       ,
                                                                                                                                                                                       m_threadId(thread_id) // 2. 对应第2个声明的m_threadId
                                                                                                                                                                                       ,
                                                                                                                                                                                       m_fiberId(fiber_id) // 3. 对应第3个声明的m_fiberId
                                                                                                                                                                                       ,
                                                                                                                                                                                       m_elapse(elapse) // 4. 对应第4个声明的m_elapse
                                                                                                                                                                                       ,
                                                                                                                                                                                       m_file(file) // 5. 对应第5个声明的m_file
                                                                                                                                                                                       ,
                                                                                                                                                                                       m_line(line), m_logger(logger), m_level(level),m_threadName(thread_name)
        {
        }

        LogLevel::Level getLevel() { return m_level; }
        std::string getContent() const { return m_ss.str(); }

        std::string getFile() const { return static_cast<std::string>(m_file); }

        uint32_t getLine() const { return m_line; }

        uint64_t getElapse() const { return m_elapse; }
        uint32_t getThreadId() const { return m_threadId; }
        uint32_t getFiberId() const { return m_fiberId; }
        uint64_t getTime() const { return m_time; }
        const std::string& getThreadName() const { return m_threadName; }
        std::stringstream &getSS() { return m_ss; }

        std::string getLoggerName() const { return m_loggerName; }

        void setContent(const std::string &content)
        {
            m_ss.clear();
            m_ss << content;
        }
        void addContent(const std::string &new_content) { m_ss << new_content; }

        std::shared_ptr<Logger> getLogger() { return m_logger; }

        void format(const char *fmt, ...)
        {
            va_list ap;
            va_start(ap, fmt);
            format(fmt, ap);
            va_end(ap);
        }

        void format(const char *fmt, va_list ap)
        {
            char *buf = nullptr;
            // 使用vasprintf动态分配内存并格式化字符串
            int len = vasprintf(&buf, fmt, ap);
            if (len != -1)
            {
                m_ss << std::string(buf, len);
                free(buf); // 释放动态分配的内存
            }
        }

        void printf(const char *fmt, ...)
        {
            va_list ap;
            va_start(ap, fmt);
            vprintf(fmt, ap);
            va_end(ap);
        }

        void vprintf(const char *fmt, va_list ap)
        {
            char *buf = nullptr;
            int len = vasprintf(&buf, fmt, ap);
            if (len != -1)
            {
                m_ss << std::string(buf, len);
                free(buf);
            }
        }

    private:
        uint64_t m_time;              // 时间戳
        uint32_t m_threadId;          // 线程ID
        uint32_t m_fiberId;           // 协程ID
        uint64_t m_elapse;            // 程序启动后流逝的毫秒数
        const char *m_file = nullptr; // 文件名
        uint64_t m_line;              // 行号
        std::stringstream m_ss;       // 日志内容
        std::shared_ptr<Logger> m_logger;
        LogLevel::Level m_level;
        std::string m_threadName;
        std::string m_loggerName;
    };

    class LogFormatter
    {
    public:
        using ptr = std::shared_ptr<LogFormatter>;
        LogFormatter(const std::string &pattern = "%d{%Y-%m-%d %H:%M:%S}%T%N%T[%p]%T%f:%l-%T%m %n");
        void init(); // 解析格式化模板
        bool getError() const { return m_error; }
        std::string format(LogEvent::ptr event);

        std::string getPattern() const { return m_pattern; }
        class FormatItem
        {
        public:
            using ptr = std::shared_ptr<FormatItem>;
            virtual ~FormatItem();
            virtual void format(std::ostream &os, LogEvent::ptr event) = 0;
        };

    private:
        std::string m_pattern;
        std::vector<FormatItem::ptr> m_items; // 格式化项列表
        bool m_error = false;
    };
    // 日志输出地基类
    class LogAppender
    {
    public:
        using ptr = std::shared_ptr<LogAppender>;
        using MutexType = Mutex;

        virtual ~LogAppender();
        virtual void log(LogEvent::ptr event) = 0;

        // 设置日志级别
        void setLevel(LogLevel::Level level) { m_level = level; }
        LogLevel::Level getLevel() const { return m_level; }

        // 设置格式化器
        void setFormatter(LogFormatter::ptr formatter)
        {
            MutexType::Lock lock(m_mutex);
            if (formatter->getError())
            {
                std::cerr << "error:setFormatter() bad LogFormatter is set"
                          << "bad format ->" << formatter->getPattern() << std::endl;
                return;
            }
            m_formatter = formatter;
            if (m_formatter)
            {
                m_hasFormatter = true;
            }
            else
            {
                m_hasFormatter = false;
            }
        }
        void setFormatter(const std::string &format)
        {
            MutexType::Lock lock(m_mutex);
            std::shared_ptr<LogFormatter> new_formatter(new LogFormatter(format));
            if (new_formatter->getError())
            {
                std::cerr << "error:setFormatter() bad LogFormatter is set"
                          << "bad format ->" << new_formatter->getPattern() << std::endl;
                return;
            }
            m_formatter = new_formatter;
            if (m_formatter)
            {
                m_hasFormatter = true;
            }
            else
            {
                m_hasFormatter = false;
            }
        }
        LogFormatter::ptr getFormatter()
        {
            MutexType::Lock lock(m_mutex);
            if (!m_hasFormatter)
            {
                return m_defaultFormatter;
            }
            return m_formatter;
        }
        virtual std::string toYamlString() = 0;

    protected:
        MutexType m_mutex;
        LogLevel::Level m_level = LogLevel::DEBUG; // 默认日志级别
        LogFormatter::ptr m_formatter;
        LogFormatter::ptr m_defaultFormatter;
        bool m_hasFormatter = false;
    };

    // 日志器
    class Logger
    {
    public:
        using ptr = std::shared_ptr<Logger>;
        using MutexType = Mutex;
        Logger(const std::string &name = "root");

        // 添加/删除输出地
        void addAppender(LogAppender::ptr appender);
        void delAppender(LogAppender::ptr appender);
        const std::list<LogAppender::ptr> &getAppenders() { return m_appenders; }

        // 日志输出接口
        void log(LogLevel::Level level, LogEvent::ptr event);
        void debug(LogEvent::ptr event);
        void info(LogEvent::ptr event);
        void warn(LogEvent::ptr event);
        void error(LogEvent::ptr event);
        void fatal(LogEvent::ptr event);
        void clearAppenders() { m_appenders.clear(); }

        uint64_t getCreateTime() const { return m_createTime; }
        LogFormatter::ptr getFormatter() { return m_formatter; }
        void setFormatter(LogFormatter::ptr formatter) { m_formatter = formatter; }
        void setFormatter(const std::string &val)
        {
            LogFormatter::ptr new_formatter(new LogFormatter(val));
            if (new_formatter->getError())
            {
                std::cerr << "function: Logger::setFormatter(const std:string& val) error" << "\tLogger m_name:" << m_name << "\tinvaild format:" << val << std::endl;
                return;
            }
            m_formatter = new_formatter;
        }

        // 设置日志级别
        void setLevel(LogLevel::Level level) { m_level = level; }
        LogLevel::Level getLevel() const { return m_level; }
        const std::string &getName() { return m_name; }
        void setName(const std::string &name) { m_name = name; }
        std::string toYamlString()
        {
            YAML::Node node;
            node["name"] = m_name;
            std::string level_str = LogLevel::ToString(m_level);
            node["level"] = level_str;
            node["appenders"] = YAML::Node(YAML::NodeType::Sequence);
            for (auto &appender : m_appenders)
            {
                std::string app_yaml = appender->toYamlString();
                YAML::Node app_node = YAML::Load(app_yaml);
                node["appenders"].push_back(app_node);
            }
            std::stringstream ss;
            ss << node;
            std::string result = ss.str();
            return result;
        }

    private:
        MutexType m_mutex;
        std::string m_name;                        // 日志器名称
        LogLevel::Level m_level = LogLevel::DEBUG; // 默认日志级别
        std::list<LogAppender::ptr> m_appenders;   // 输出地列表
        LogFormatter::ptr m_formatter;
        uint64_t m_createTime;
        Logger::ptr m_root;
    };
    class LogEventWrap
    {
    public:
        LogEventWrap(std::shared_ptr<class Logger> logger, std::shared_ptr<class LogEvent> event, LogLevel::Level level);
        ~LogEventWrap();
        std::stringstream &getSS();
        LogEvent::ptr getLogEvent() const { return m_event; }

    private:
        std::shared_ptr<class Logger> m_logger;  // 日志器
        std::shared_ptr<class LogEvent> m_event; // 日志事件
        LogLevel::Level m_level;                 // 日志级别
    };

    class StdoutLogAppender : public LogAppender
    {
    public:
        using MutexTyep = Mutex;
        using ptr = std::shared_ptr<StdoutLogAppender>;
        StdoutLogAppender()
        {
            m_formatter=std::make_shared<LogFormatter>();
            m_defaultFormatter=std::make_shared<LogFormatter>();
        }
        void log(LogEvent::ptr event) override;
        std::string toYamlString() override
        {
            MutexType::Lock lock(m_mutex);
            YAML::Node node;
            node["type"] = "StdoutLogAppender";
            std::string level_str = LogLevel::ToString(m_level);
            node["level"] = level_str;
            std::stringstream ss;
            ss << node;
            std::string result = ss.str();
            return result;
        }
    };

    class FileLogAppender : public LogAppender
    {
    public:
        using MutexTyep = Mutex;
        using ptr = std::shared_ptr<FileLogAppender>;
        FileLogAppender(const std::string &filename, uint64_t check_interval = 1000);
        void log(LogEvent::ptr event) override;
        std::string getFile()
        {
            return m_filename;
        }
        bool reopen(); // 重新打开文件
        std::string toYamlString() override
        {
            MutexType::Lock lock(m_mutex);
            if (m_filename.empty())
            {
                // 输出错误日志：文件路径未设置
                std::cerr
                    << "FileLogAppender[" << this << "] toYamlString error: filename is empty";
            }

            YAML::Node node;

            node["type"] = "FileLogAppender";

            node["file"] = m_filename;
            std::string level_str = LogLevel::ToString(m_level);
            node["level"] = level_str;
            std::stringstream ss;
            ss << node;
            std::string result = ss.str();

            return result;
        }

    private:
        std::string m_filename;
        std::fstream m_filestream;

        uint64_t m_checkInterval;                         // 先声明m_checkInterval
        std::chrono::steady_clock::time_point m_lastTime; // 后声明m_lastTime

        bool m_reopenError = false;
    };
    class LoggerManager : public Singleton<LoggerManager>
    {
        friend class Singleton<LoggerManager>; // 允许单例基类访问私有构造函数
    public:
        using ptr = std::shared_ptr<LoggerManager>;
        using MutexType = Mutex;

        // 获取各级别默认日志器
        Logger::ptr getDebugLogger() const { return m_debugLogger; }
        Logger::ptr getInfoLogger() const { return m_infoLogger; }
        Logger::ptr getWarnLogger() const { return m_warnLogger; }
        Logger::ptr getErrorLogger() const { return m_errorLogger; }
        Logger::ptr getFatalLogger() const { return m_fatalLogger; }
        void addLogger(const std::string &index, Logger::ptr val)
        {
            MutexType::Lock lock(m_mutex);
            m_loggers[index] = val;
        }
        Logger::ptr getLogger(const std::string &name)
        {
            MutexType::Lock lock(m_mutex);
            auto it = m_loggers.find(name);
            if (it != m_loggers.end())
            {
                return it->second;
            }
            Logger::ptr tmp_logger = std::make_shared<Logger>(name);
            tmp_logger->setLevel(m_default_level);
            StdoutLogAppender::ptr stdout_appender = std::make_shared<StdoutLogAppender>();
            stdout_appender->setFormatter(std::make_shared<LogFormatter>(
                "%d{%Y-%m-%d %H:%M:%S}%T%N%T[%p]%T%f:%l-%T%m %n"));
            tmp_logger->addAppender(stdout_appender);
            m_loggers[name] = tmp_logger;
            return tmp_logger;
        };

        std::string toYamlString()
        {
            MutexType::Lock lock(m_mutex);
            YAML::Node node;
            for (auto &i : m_loggers)
            {
                node.push_back(YAML::Load(i.second->toYamlString()));
            }
            std::stringstream ss;
            ss << node;
            return ss.str();
        }

        Logger::ptr getRoot() { return m_root; }
        LogLevel::Level getLevel()
        {
            return m_default_level;
        }
        void setLevel(LogLevel::Level level)
        {
             m_default_level=level;
        }

    private:
        // 私有构造函数（单例模式）
        MutexType m_mutex;

        std::map<std::string, Logger::ptr> m_loggers; // 不包括
        std::string m_name = "root";
        Logger::ptr m_root;
        LoggerManager();
        LogLevel::Level m_default_level = LogLevel::Level::INFO;

        // 各级别默认日志器
        Logger::ptr m_debugLogger;
        Logger::ptr m_infoLogger;
        Logger::ptr m_warnLogger;
        Logger::ptr m_errorLogger;
        Logger::ptr m_fatalLogger;
    };

    // 文件日志输出地

    // 日志器管理单例类（使用提供的Singleton模板）

} // namespace sylar

#endif // SYLAR_LOG_H
